package net.xo68.destiny.starter.common;

import com.fasterxml.jackson.databind.ObjectMapper;
import net.xo68.destiny.contract.domain.report.DatagramSerializer;
import net.xo68.destiny.core.discovery.NodeDiscoveryClient;
import net.xo68.destiny.core.discovery.NodeDiscoveryRunner;
import net.xo68.destiny.core.json.JsonMapper;
import net.xo68.destiny.core.rpc.RpcClient;
import net.xo68.destiny.core.rpc.impl.RpcClientImpl;
import net.xo68.destiny.core.serialize.JsonDatagramSerializer;
import net.xo68.destiny.starter.common.sched.DestinyTimingWheelScheduler;
import net.xo68.destiny.starter.common.sched.TaskTimeoutEventHandler;
import net.xo68.destiny.starter.common.sched.impl.DestinyTimingWheelSchedulerImpl;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.client.RestTemplate;

@Configuration
@EnableConfigurationProperties({SchedulerCommonProperties.class,TimingWheelProperties.class})
@ConditionalOnProperty(prefix = "destiny.common", value = "enable",havingValue = "true", matchIfMissing = true)
@ComponentScan(basePackages={"net.xo68.destiny.starter.common.context",
        "net.xo68.destiny.starter.common.sched"})
@Import({StartupRuner.class})
public class SchedulerCommonConfiguration {

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Bean
    @ConditionalOnMissingBean(JsonMapper.class)
    public JsonMapper jsonMapper(ObjectMapper objectMapper){
        return new JsonMapper(objectMapper);
    }



    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Bean
    @ConditionalOnMissingBean(NodeDiscoveryClient.class)
    public NodeDiscoveryClient nodeDiscoveryClient(SchedulerCommonProperties schedulerCommonProperties, NodeDiscoveryRunner nodeDiscoveryRunner){
        return new NodeDiscoveryClient(nodeDiscoveryRunner,schedulerCommonProperties.getHeartbeatPeriodSecond());
    }

    @Bean
    @ConditionalOnMissingBean(DatagramSerializer.class)
    public DatagramSerializer datagramSerializer(JsonMapper jsonMapper){
        return new JsonDatagramSerializer(jsonMapper);
    }

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Bean
    @ConditionalOnMissingBean(RpcClient.class)
    public RpcClient rpcClient(RestTemplate restTemplate, SchedulerCommonProperties schedulerCommonProperties){
        return new RpcClientImpl(RpcClient.PROTOCOL_HTTP,restTemplate, schedulerCommonProperties.getRpcRetryCount());
    }

    @Bean
    @ConditionalOnMissingBean(DestinyTimingWheelScheduler.class)
    @ConditionalOnProperty(prefix = "destiny.timewheel", value = "enable",havingValue = "true", matchIfMissing = true)
    public DestinyTimingWheelScheduler destinyTimingWheelScheduler(TimingWheelProperties timingWheelProperties, TaskTimeoutEventHandler taskTimeoutEventHandler){
        return new DestinyTimingWheelSchedulerImpl(timingWheelProperties,taskTimeoutEventHandler);
    }
}
